/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HIVIEWDFX_HICOLLIE_H
#define HIVIEWDFX_HICOLLIE_H
/**
 * @addtogroup HiCollie
 * @{
 *
 * @brief 提供检测业务线程卡死或卡顿的能力。请注意：要在非业务线程中调用
 *
 * 本模块函数可用于：
*（1）注册应用业务线程卡死的周期性检测任务；
*（2）注册应用业务线程卡顿检测的回调函数；
*（3）上报应用业务线程卡死事件.
 *
 * @since 12
 */

/**
 * @file hicollie.h
 *
 * @brief HiCollie模块对外提供检测业务线程卡死、卡顿，以及上报卡死事件的能力。
 * @kit PerformanceAnalysisKit
 * @library libohhicollie.so
 * @syscap SystemCapability.HiviewDFX.HiProfiler.HiCollie
 * @since 12
 */

#include <time.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 错误码定义
 *
 * @since 12
 */
typedef enum HiCollie_ErrorCode  {
    /** 成功 */
    HICOLLIE_SUCCESS  = 0,
    /** 无效参数，可能的原因： 1.参数传值问题 2.参数类型问题 */
    HICOLLIE_INVALID_ARGUMENT  = 401,
    /** 检测的线程错误：在业务线程中调用 */
    HICOLLIE_WRONG_THREAD_CONTEXT = 29800001,
    /** 远程调用错误 */
    HICOLLIE_REMOTE_FAILED = 29800002,
} HiCollie_ErrorCode;

/**
 * @brief 在业务线程卡死检测中，通过实现该函数来检测业务线程是否卡住。
 * HiCollie将在独立线程中每3秒调用一次该函数。
 * 例如：该函数可实现向业务线程发送消息。在业务线程接收到消息之后，设置一个标记，通过检查这个标记，可以知道业务线程是否卡住。
 *
 * @since 12
 */
typedef void (*OH_HiCollie_Task)(void);

/**
 * @brief 事件处理前调用该函数。在卡顿检测中, 通过实现该函数来记录业务线程处理事件的开始时间。
 *
 * @param eventName 业务线程处理事件的名字。
 * @since 12
 */
typedef void (*OH_HiCollie_BeginFunc)(const char* eventName);

/**
 * @brief 事件处理后调用该函数。在卡顿检测中, 通过实现该函数来检测业务线程处理事件是否卡顿。
 * 通过检查处理事件的执行时间，HiCollie将知道每个事件的持续时间。如果超过预设阈值(150ms~450ms)，将报告jank事件。
 *
 * @param eventName Business thread processing event name。
 * @since 12
 */
typedef void (*OH_HiCollie_EndFunc)(const char* eventName);

/**
 * @brief 用于检测业务线程卡顿的参数。
 * 请注意，这些参数对API 12无效，仅用于扩展。
 *
 * @since 12
 */
typedef struct HiCollie_DetectionParam {
    /** 扩展参数以供将来使用。 */
    int sampleStackTriggerTime;
    /** 扩展参数以供将来使用。 */
    int reserved;
} HiCollie_DetectionParam;

/**
 * @brief 注册应用业务线程卡死的周期性检测任务。
 *
 * @param task 每3秒执行一次的周期性检测任务，用于检测业务线程是否卡住。
 * @return {@link HICOLLIE_SUCCESS} 0 - 成功。
 *         {@link HICOLLIE_WRONG_THREAD_CONTEXT} 29800001 - 调用线程错误。无法从主线程调用该函数。
 * @since 12
 */
HiCollie_ErrorCode OH_HiCollie_Init_StuckDetection(OH_HiCollie_Task task);

/**
 * @brief 注册应用业务线程卡顿检测的回调函数。
 *
 * @param beginFunc 检测业务线程处理事件前的函数。
 * @param endFunc 检测业务线程处理事件后的函数。
 * @param param 扩展参数以供将来使用。
 * @return {@link HICOLLIE_SUCCESS} 0 - 成功。
 *         {@link HICOLLIE_INVALID_ARGUMENT} 401 - 开始函数和结束函数两者都必须有值或为空，否则将返回该错误值。
 *         {@link HICOLLIE_WRONG_THREAD_CONTEXT} 29800001 - 调用线程错误。无法从主线程调用该函数。
 * @since 12
 */
HiCollie_ErrorCode OH_HiCollie_Init_JankDetection(OH_HiCollie_BeginFunc* beginFunc,
    OH_HiCollie_EndFunc* endFunc, HiCollie_DetectionParam param);

/**
 * @brief 上报应用业务线程卡死事件。
 *
 * @param isSixSecond 布尔指针。布尔指针的值。如果卡住6秒，则为真。如果卡住3秒，则为False。
 * @return {@link HICOLLIE_SUCCESS} 0 - 成功。
 *         {@link HICOLLIE_INVALID_ARGUMENT} 401 - 开始函数和结束函数两者都必须有值或为空，否则将返回该错误值。
 *         {@link HICOLLIE_WRONG_THREAD_CONTEXT} 29800001 - 调用线程错误。无法从主线程调用该函数。
 *         {@link HICOLLIE_REMOTE_FAILED} 29800002 - 远程调用错误。
 * @since 12
 */
HiCollie_ErrorCode OH_HiCollie_Report(bool* isSixSecond);

#ifdef __cplusplus
}
#endif
/** @} */

#endif // HIVIEWDFX_HICOLLIE_H
